/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.ces4.produccion.jpa.controllers;

import co.com.ces4.produccion.jpa.controllers.exceptions.IllegalOrphanException;
import co.com.ces4.produccion.jpa.controllers.exceptions.NonexistentEntityException;
import co.com.ces4.produccion.jpa.controllers.exceptions.PreexistingEntityException;
import co.com.ces4.produccion.jpa.entities.Articulo;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import co.com.ces4.produccion.jpa.entities.ArticuloLinea;
import java.util.ArrayList;
import java.util.List;
import co.com.ces4.produccion.jpa.entities.MateriaPrimaArticulo;
import co.com.ces4.produccion.jpa.entities.DetalleSolicitudProduccion;

/**
 *
 * @author usuario
 */
public class ArticuloJpaController implements Serializable {

    public ArticuloJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Articulo articulo) throws PreexistingEntityException, Exception {
        if (articulo.getArticuloLineaList() == null) {
            articulo.setArticuloLineaList(new ArrayList<ArticuloLinea>());
        }
        if (articulo.getMateriaPrimaArticuloList() == null) {
            articulo.setMateriaPrimaArticuloList(new ArrayList<MateriaPrimaArticulo>());
        }
        if (articulo.getDetalleSolicitudProduccionList() == null) {
            articulo.setDetalleSolicitudProduccionList(new ArrayList<DetalleSolicitudProduccion>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            em.persist(articulo);
            /*List<ArticuloLinea> attachedArticuloLineaList = new ArrayList<ArticuloLinea>();
            for (ArticuloLinea articuloLineaListArticuloLineaToAttach : articulo.getArticuloLineaList()) {
                articuloLineaListArticuloLineaToAttach = em.getReference(articuloLineaListArticuloLineaToAttach.getClass(), articuloLineaListArticuloLineaToAttach.getArticuloLineaPK());
                attachedArticuloLineaList.add(articuloLineaListArticuloLineaToAttach);
            }
            articulo.setArticuloLineaList(attachedArticuloLineaList);
            List<MateriaPrimaArticulo> attachedMateriaPrimaArticuloList = new ArrayList<MateriaPrimaArticulo>();
            for (MateriaPrimaArticulo materiaPrimaArticuloListMateriaPrimaArticuloToAttach : articulo.getMateriaPrimaArticuloList()) {
                materiaPrimaArticuloListMateriaPrimaArticuloToAttach = em.getReference(materiaPrimaArticuloListMateriaPrimaArticuloToAttach.getClass(), materiaPrimaArticuloListMateriaPrimaArticuloToAttach.getMateriaPrimaArticuloPK());
                attachedMateriaPrimaArticuloList.add(materiaPrimaArticuloListMateriaPrimaArticuloToAttach);
            }
            articulo.setMateriaPrimaArticuloList(attachedMateriaPrimaArticuloList);
            List<DetalleSolicitudProduccion> attachedDetalleSolicitudProduccionList = new ArrayList<DetalleSolicitudProduccion>();
            for (DetalleSolicitudProduccion detalleSolicitudProduccionListDetalleSolicitudProduccionToAttach : articulo.getDetalleSolicitudProduccionList()) {
                detalleSolicitudProduccionListDetalleSolicitudProduccionToAttach = em.getReference(detalleSolicitudProduccionListDetalleSolicitudProduccionToAttach.getClass(), detalleSolicitudProduccionListDetalleSolicitudProduccionToAttach.getDetalleSolicitudProduccionPK());
                attachedDetalleSolicitudProduccionList.add(detalleSolicitudProduccionListDetalleSolicitudProduccionToAttach);
            }
            articulo.setDetalleSolicitudProduccionList(attachedDetalleSolicitudProduccionList);
            em.persist(articulo);
            for (ArticuloLinea articuloLineaListArticuloLinea : articulo.getArticuloLineaList()) {
                Articulo oldArticuloOfArticuloLineaListArticuloLinea = articuloLineaListArticuloLinea.getArticulo();
                articuloLineaListArticuloLinea.setArticulo(articulo);
                articuloLineaListArticuloLinea = em.merge(articuloLineaListArticuloLinea);
                if (oldArticuloOfArticuloLineaListArticuloLinea != null) {
                    oldArticuloOfArticuloLineaListArticuloLinea.getArticuloLineaList().remove(articuloLineaListArticuloLinea);
                    oldArticuloOfArticuloLineaListArticuloLinea = em.merge(oldArticuloOfArticuloLineaListArticuloLinea);
                }
            }
            for (MateriaPrimaArticulo materiaPrimaArticuloListMateriaPrimaArticulo : articulo.getMateriaPrimaArticuloList()) {
                Articulo oldArticuloOfMateriaPrimaArticuloListMateriaPrimaArticulo = materiaPrimaArticuloListMateriaPrimaArticulo.getArticulo();
                materiaPrimaArticuloListMateriaPrimaArticulo.setArticulo(articulo);
                materiaPrimaArticuloListMateriaPrimaArticulo = em.merge(materiaPrimaArticuloListMateriaPrimaArticulo);
                if (oldArticuloOfMateriaPrimaArticuloListMateriaPrimaArticulo != null) {
                    oldArticuloOfMateriaPrimaArticuloListMateriaPrimaArticulo.getMateriaPrimaArticuloList().remove(materiaPrimaArticuloListMateriaPrimaArticulo);
                    oldArticuloOfMateriaPrimaArticuloListMateriaPrimaArticulo = em.merge(oldArticuloOfMateriaPrimaArticuloListMateriaPrimaArticulo);
                }
            }
            for (DetalleSolicitudProduccion detalleSolicitudProduccionListDetalleSolicitudProduccion : articulo.getDetalleSolicitudProduccionList()) {
                Articulo oldArticuloOfDetalleSolicitudProduccionListDetalleSolicitudProduccion = detalleSolicitudProduccionListDetalleSolicitudProduccion.getArticulo();
                detalleSolicitudProduccionListDetalleSolicitudProduccion.setArticulo(articulo);
                detalleSolicitudProduccionListDetalleSolicitudProduccion = em.merge(detalleSolicitudProduccionListDetalleSolicitudProduccion);
                if (oldArticuloOfDetalleSolicitudProduccionListDetalleSolicitudProduccion != null) {
                    oldArticuloOfDetalleSolicitudProduccionListDetalleSolicitudProduccion.getDetalleSolicitudProduccionList().remove(detalleSolicitudProduccionListDetalleSolicitudProduccion);
                    oldArticuloOfDetalleSolicitudProduccionListDetalleSolicitudProduccion = em.merge(oldArticuloOfDetalleSolicitudProduccionListDetalleSolicitudProduccion);
                }
            }*/
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findArticulo(articulo.getDsid()) != null) {
                throw new PreexistingEntityException("Articulo " + articulo + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Articulo articulo) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Articulo persistentArticulo = em.find(Articulo.class, articulo.getDsid());
            List<ArticuloLinea> articuloLineaListOld = persistentArticulo.getArticuloLineaList();
            List<ArticuloLinea> articuloLineaListNew = articulo.getArticuloLineaList();
            List<MateriaPrimaArticulo> materiaPrimaArticuloListOld = persistentArticulo.getMateriaPrimaArticuloList();
            List<MateriaPrimaArticulo> materiaPrimaArticuloListNew = articulo.getMateriaPrimaArticuloList();
            List<DetalleSolicitudProduccion> detalleSolicitudProduccionListOld = persistentArticulo.getDetalleSolicitudProduccionList();
            List<DetalleSolicitudProduccion> detalleSolicitudProduccionListNew = articulo.getDetalleSolicitudProduccionList();
            List<String> illegalOrphanMessages = null;
            for (ArticuloLinea articuloLineaListOldArticuloLinea : articuloLineaListOld) {
                if (!articuloLineaListNew.contains(articuloLineaListOldArticuloLinea)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain ArticuloLinea " + articuloLineaListOldArticuloLinea + " since its articulo field is not nullable.");
                }
            }
            for (MateriaPrimaArticulo materiaPrimaArticuloListOldMateriaPrimaArticulo : materiaPrimaArticuloListOld) {
                if (!materiaPrimaArticuloListNew.contains(materiaPrimaArticuloListOldMateriaPrimaArticulo)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain MateriaPrimaArticulo " + materiaPrimaArticuloListOldMateriaPrimaArticulo + " since its articulo field is not nullable.");
                }
            }
            for (DetalleSolicitudProduccion detalleSolicitudProduccionListOldDetalleSolicitudProduccion : detalleSolicitudProduccionListOld) {
                if (!detalleSolicitudProduccionListNew.contains(detalleSolicitudProduccionListOldDetalleSolicitudProduccion)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain DetalleSolicitudProduccion " + detalleSolicitudProduccionListOldDetalleSolicitudProduccion + " since its articulo field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<ArticuloLinea> attachedArticuloLineaListNew = new ArrayList<ArticuloLinea>();
            for (ArticuloLinea articuloLineaListNewArticuloLineaToAttach : articuloLineaListNew) {
                articuloLineaListNewArticuloLineaToAttach = em.getReference(articuloLineaListNewArticuloLineaToAttach.getClass(), articuloLineaListNewArticuloLineaToAttach.getArticuloLineaPK());
                attachedArticuloLineaListNew.add(articuloLineaListNewArticuloLineaToAttach);
            }
            articuloLineaListNew = attachedArticuloLineaListNew;
            articulo.setArticuloLineaList(articuloLineaListNew);
            List<MateriaPrimaArticulo> attachedMateriaPrimaArticuloListNew = new ArrayList<MateriaPrimaArticulo>();
            for (MateriaPrimaArticulo materiaPrimaArticuloListNewMateriaPrimaArticuloToAttach : materiaPrimaArticuloListNew) {
                materiaPrimaArticuloListNewMateriaPrimaArticuloToAttach = em.getReference(materiaPrimaArticuloListNewMateriaPrimaArticuloToAttach.getClass(), materiaPrimaArticuloListNewMateriaPrimaArticuloToAttach.getMateriaPrimaArticuloPK());
                attachedMateriaPrimaArticuloListNew.add(materiaPrimaArticuloListNewMateriaPrimaArticuloToAttach);
            }
            materiaPrimaArticuloListNew = attachedMateriaPrimaArticuloListNew;
            articulo.setMateriaPrimaArticuloList(materiaPrimaArticuloListNew);
            List<DetalleSolicitudProduccion> attachedDetalleSolicitudProduccionListNew = new ArrayList<DetalleSolicitudProduccion>();
            for (DetalleSolicitudProduccion detalleSolicitudProduccionListNewDetalleSolicitudProduccionToAttach : detalleSolicitudProduccionListNew) {
                detalleSolicitudProduccionListNewDetalleSolicitudProduccionToAttach = em.getReference(detalleSolicitudProduccionListNewDetalleSolicitudProduccionToAttach.getClass(), detalleSolicitudProduccionListNewDetalleSolicitudProduccionToAttach.getDetalleSolicitudProduccionPK());
                attachedDetalleSolicitudProduccionListNew.add(detalleSolicitudProduccionListNewDetalleSolicitudProduccionToAttach);
            }
            detalleSolicitudProduccionListNew = attachedDetalleSolicitudProduccionListNew;
            articulo.setDetalleSolicitudProduccionList(detalleSolicitudProduccionListNew);
            articulo = em.merge(articulo);
            for (ArticuloLinea articuloLineaListNewArticuloLinea : articuloLineaListNew) {
                if (!articuloLineaListOld.contains(articuloLineaListNewArticuloLinea)) {
                    Articulo oldArticuloOfArticuloLineaListNewArticuloLinea = articuloLineaListNewArticuloLinea.getArticulo();
                    articuloLineaListNewArticuloLinea.setArticulo(articulo);
                    articuloLineaListNewArticuloLinea = em.merge(articuloLineaListNewArticuloLinea);
                    if (oldArticuloOfArticuloLineaListNewArticuloLinea != null && !oldArticuloOfArticuloLineaListNewArticuloLinea.equals(articulo)) {
                        oldArticuloOfArticuloLineaListNewArticuloLinea.getArticuloLineaList().remove(articuloLineaListNewArticuloLinea);
                        oldArticuloOfArticuloLineaListNewArticuloLinea = em.merge(oldArticuloOfArticuloLineaListNewArticuloLinea);
                    }
                }
            }
            for (MateriaPrimaArticulo materiaPrimaArticuloListNewMateriaPrimaArticulo : materiaPrimaArticuloListNew) {
                if (!materiaPrimaArticuloListOld.contains(materiaPrimaArticuloListNewMateriaPrimaArticulo)) {
                    Articulo oldArticuloOfMateriaPrimaArticuloListNewMateriaPrimaArticulo = materiaPrimaArticuloListNewMateriaPrimaArticulo.getArticulo();
                    materiaPrimaArticuloListNewMateriaPrimaArticulo.setArticulo(articulo);
                    materiaPrimaArticuloListNewMateriaPrimaArticulo = em.merge(materiaPrimaArticuloListNewMateriaPrimaArticulo);
                    if (oldArticuloOfMateriaPrimaArticuloListNewMateriaPrimaArticulo != null && !oldArticuloOfMateriaPrimaArticuloListNewMateriaPrimaArticulo.equals(articulo)) {
                        oldArticuloOfMateriaPrimaArticuloListNewMateriaPrimaArticulo.getMateriaPrimaArticuloList().remove(materiaPrimaArticuloListNewMateriaPrimaArticulo);
                        oldArticuloOfMateriaPrimaArticuloListNewMateriaPrimaArticulo = em.merge(oldArticuloOfMateriaPrimaArticuloListNewMateriaPrimaArticulo);
                    }
                }
            }
            for (DetalleSolicitudProduccion detalleSolicitudProduccionListNewDetalleSolicitudProduccion : detalleSolicitudProduccionListNew) {
                if (!detalleSolicitudProduccionListOld.contains(detalleSolicitudProduccionListNewDetalleSolicitudProduccion)) {
                    Articulo oldArticuloOfDetalleSolicitudProduccionListNewDetalleSolicitudProduccion = detalleSolicitudProduccionListNewDetalleSolicitudProduccion.getArticulo();
                    detalleSolicitudProduccionListNewDetalleSolicitudProduccion.setArticulo(articulo);
                    detalleSolicitudProduccionListNewDetalleSolicitudProduccion = em.merge(detalleSolicitudProduccionListNewDetalleSolicitudProduccion);
                    if (oldArticuloOfDetalleSolicitudProduccionListNewDetalleSolicitudProduccion != null && !oldArticuloOfDetalleSolicitudProduccionListNewDetalleSolicitudProduccion.equals(articulo)) {
                        oldArticuloOfDetalleSolicitudProduccionListNewDetalleSolicitudProduccion.getDetalleSolicitudProduccionList().remove(detalleSolicitudProduccionListNewDetalleSolicitudProduccion);
                        oldArticuloOfDetalleSolicitudProduccionListNewDetalleSolicitudProduccion = em.merge(oldArticuloOfDetalleSolicitudProduccionListNewDetalleSolicitudProduccion);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = articulo.getDsid();
                if (findArticulo(id) == null) {
                    throw new NonexistentEntityException("The articulo with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Articulo articulo;
            try {
                articulo = em.getReference(Articulo.class, id);
                articulo.getDsid();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The articulo with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<ArticuloLinea> articuloLineaListOrphanCheck = articulo.getArticuloLineaList();
            for (ArticuloLinea articuloLineaListOrphanCheckArticuloLinea : articuloLineaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Articulo (" + articulo + ") cannot be destroyed since the ArticuloLinea " + articuloLineaListOrphanCheckArticuloLinea + " in its articuloLineaList field has a non-nullable articulo field.");
            }
            List<MateriaPrimaArticulo> materiaPrimaArticuloListOrphanCheck = articulo.getMateriaPrimaArticuloList();
            for (MateriaPrimaArticulo materiaPrimaArticuloListOrphanCheckMateriaPrimaArticulo : materiaPrimaArticuloListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Articulo (" + articulo + ") cannot be destroyed since the MateriaPrimaArticulo " + materiaPrimaArticuloListOrphanCheckMateriaPrimaArticulo + " in its materiaPrimaArticuloList field has a non-nullable articulo field.");
            }
            List<DetalleSolicitudProduccion> detalleSolicitudProduccionListOrphanCheck = articulo.getDetalleSolicitudProduccionList();
            for (DetalleSolicitudProduccion detalleSolicitudProduccionListOrphanCheckDetalleSolicitudProduccion : detalleSolicitudProduccionListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Articulo (" + articulo + ") cannot be destroyed since the DetalleSolicitudProduccion " + detalleSolicitudProduccionListOrphanCheckDetalleSolicitudProduccion + " in its detalleSolicitudProduccionList field has a non-nullable articulo field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(articulo);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Articulo> findArticuloEntities() {
        return findArticuloEntities(true, -1, -1);
    }

    public List<Articulo> findArticuloEntities(int maxResults, int firstResult) {
        return findArticuloEntities(false, maxResults, firstResult);
    }

    private List<Articulo> findArticuloEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Articulo.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Articulo findArticulo(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Articulo.class, id);
        } finally {
            em.close();
        }
    }

    public int getArticuloCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Articulo> rt = cq.from(Articulo.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

    public List<Articulo> getArticuloList(String codigo, String descripcion) {
        EntityManager em = getEntityManager();
        try {
            StringBuilder sb = new StringBuilder("SELECT articulo FROM Articulo articulo WHERE 1=1 ");
            if (codigo != null) {
                sb.append("AND (articulo.dsid LIKE :DSID ");
                if (descripcion != null) {
                    sb.append("AND articulo.dsdescripcion LIKE :DSDESCRIPCION");
                }
                sb.append(")");
            } else if (descripcion != null) {
                sb.append("AND articulo.dsdescripcion LIKE :DSDESCRIPCION");
            }

            Query query = em.createQuery(sb.toString());
            if (codigo != null) {
                query.setParameter("DSID", "%" + codigo + "%");
            }
            if (descripcion != null) {
                query.setParameter("DSDESCRIPCION", "%" + descripcion + "%");
            }

            List<Articulo> articulos = query.getResultList();
            return articulos;
        } finally {
            em.close();
        }
    }
}
